package org.easy.web.service.db.impl;

import org.easy.db.*;
import org.easy.db.generator.GeneratorBody;
import org.easy.exception.SqlException;
import org.easy.web.service.db.DataBaseService;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @Description:
 * @Author: wxl
 * @CreateTime: 2023/1/17 8:54
 */
@Service
public class DataBaseServiceImpl implements DataBaseService {

    private static final IConnectManager CONNECT_MANAGER = new ConnectManager();

    /**
     * 数据库连接
     * @param dataBase 数据库基本信息
     */
    @Override
    public boolean connect(DataBaseInfo dataBase) {
        try {
            DataBaseFactory factory = CONNECT_MANAGER.get(dataBase.getDataBase());
            if (Objects.isNull(factory)) {
                dataBase.initDataSource();
                factory = new DataBaseFactory(dataBase);
                factory.connect();
                CONNECT_MANAGER.put(dataBase.getDataBase(), factory);
            }
            return Boolean.TRUE;
        } catch (Exception e) {
            throw new SqlException(e.getMessage());
        }
    }

    /**
     * 查询表名
     *
     * @param dataBase 数据库
     * @return Map<String, List < String>>
     */
    @Override
    public Map<String, List<String>> getTableName(String dataBase) {
        DataBaseFactory factory = CONNECT_MANAGER.get(dataBase);
        validateFactory(factory,dataBase);
        return factory.queryTableNamesByDbName(dataBase);
    }

    /**
     * 根据数据库查询
     *
     * @param dataBase 数据库
     * @param sql      查询语句
     * @return List<Map < String, Object>>
     */
    @Override
    public List<Map<String, Object>> queryByDataBase(String dataBase, String sql) {
        DataBaseFactory factory = CONNECT_MANAGER.get(dataBase);
        validateFactory(factory,dataBase);
        try {
            return factory.query(sql);
        } catch (DataAccessException e) {
            throw new SqlException(e.getMessage());
        }
    }

    /**
     * 根据数据库删除
     *
     * @param dataBase 数据库
     * @param sql      删除语句
     * @return int
     */
    @Override
    public int deleteByDataBase(String dataBase, String sql) {
        DataBaseFactory factory = CONNECT_MANAGER.get(dataBase);
        validateFactory(factory,dataBase);
        try {
            return factory.delete(sql);
        } catch (DataAccessException e) {
            throw new SqlException(e.getMessage());
        }

    }

    /**
     * 根据数据库更新
     *
     * @param dataBase 数据库
     * @param sql      更新语句
     * @return int
     */
    @Override
    public int updateByDataBase(String dataBase, String sql) {
        DataBaseFactory factory = CONNECT_MANAGER.get(dataBase);
        validateFactory(factory,dataBase);
        try {
            return factory.update(sql);
        } catch (DataAccessException e) {
            throw new SqlException(e.getMessage());
        }
    }

    /**
     * 代码生成
     *
     * @param body 生成代码的参数
     */
    @Override
    public void generator(GeneratorBody body) {
        DataBaseFactory factory = CONNECT_MANAGER.get(body.getDataBase());
        validateFactory(factory,body.getDataBase());
        factory.generator(body.getGlobalConfig());
    }

    /**
     * 执行alter语句
     *
     * @param dataBase 数据库
     * @param sql      alter语句
     */
    @Override
    public void alterSql(String dataBase, String sql) {
        DataBaseFactory factory = CONNECT_MANAGER.get(dataBase);
        validateFactory(factory,dataBase);
        try {
            factory.alter(sql);
        } catch (DataAccessException e) {
            throw new SqlException(e.getMessage());
        }
    }

    /**
     * 执行create语句
     *
     * @param dataBase 数据库
     * @param sql      alter语句
     */
    @Override
    public void createSql(String dataBase, String sql) {
        DataBaseFactory factory = CONNECT_MANAGER.get(dataBase);
        validateFactory(factory,dataBase);
        try {
            factory.create(sql);
        } catch (DataAccessException e) {
            throw new SqlException(e.getMessage());
        }
    }

    private void validateFactory(DataBaseFactory factory,String dataBase) {
        if (Objects.isNull(factory)) {
            throw new SqlException("数据库["+dataBase+"]未连接,不能执行SQL;");
        }
    }

}
